#ifndef __UISELL_LAYER_H__
#define __UISELL_LAYER_H__

#include "gofgame/common/cxx_0x.h"
#include "gofgame/common/Ref.h"
#include "gofgame/common/ui/Intent.h"
#include <cocos2d.h>
#include <list>

namespace gofgame {
	namespace common {
		namespace ui {

			using namespace gofgame::common;
			using namespace cocos2d;
			using namespace std;

			class Component;

			class Dialog;

			class UIShellLayer : public CCLayer {
			public:
				static UIShellLayer *getUIShellLayer(CCScene *scene = nullptr);
				virtual bool init() _override;
				virtual void onEnter() _override;
				virtual void onExit() _override;

				virtual void addChild(CCNode *child) _override _final;
				virtual void addChild(CCNode *child, int zOrder) _override _final;
				virtual void addChild(CCNode *child, int zOrder, int tag) _override _final;
				virtual void removeChild(CCNode *child) _override  _final;
				virtual void removeChild(CCNode *child, bool cleanup) _override  _final;
				virtual void removeChildByTag(int tag) _override  _final;
				virtual void removeChildByTag(int tag, bool cleanup) _override  _final;
				virtual void removeAllChildren() _override  _final;
				virtual void removeAllChildrenWithCleanup(bool cleanup) _override _final;

				void forward(Intent *intent);
				void refresh();
				void back();

				Component *getTouchedComponent() const;
				const CCPoint &getBeganTouchFigurePoint() const;
				const CCPoint &getPreviousFigurePoint() const;
				const CCPoint &getCurrentFigurePoint() const;

				virtual void visit() _override;

			public:
				//Fuck cocos2d-x and apple's design pattern
				//These event methods have to be public, it's too ugly!!!
				virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) _override;
				virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) _override;
				virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) _override;
				virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) _override;

			private:
				UIShellLayer();
				void show(Component *component);
				void updateVisiblity();
				Ref<CCNode> componentNode;
				Ref<CCNode> dialogNode;
				Ref<Component> touchedComponent;
				Ref<Component> componentThatCancelTouchBeganBubble;
				list<Ref<Intent>> intentStack;
				CCPoint beganTouchFigurePoint;
				CCPoint previousFigurePoint;
				CCPoint currentFigurePoint;

				Component *componentAtPoint(const CCPoint &point);
				Component *componentAtPoint(CCNode *node, const CCPoint &point, bool &foreceReturnNullPtr);
				friend class gofgame::common::ui::Dialog;
			};
		}
	}
}

#endif //__UISELL_LAYER_H__
